/**
 * 用于搜索对象中的符合正则表达式的字段
 * @date 2020-08-18
 * @param {Object} arr
 * @param {RegExp} name
 * @param {Number} deep=5
 * @returns {Object}
 */
function searchObj(arr, name, deep = 5) {
  if (!deep) {
    return [];
  }
  deep -= 1;
  return arr.reduce((all, i) => {
    //判断 key 中是否有符合项
    if (name.test(i[0])) {
      all.push(i);
      return all;
    } else {
      //判断数据类型 分类操作
      let type = Object.prototype.toString.call(i[1]).match(/(?<=\[object\s+)\S+?(?=\])/)[0];
      switch (type) {
        //字符串和函数只需要对文字部分分析就可以了
        case "String":
          return name.test(i[1]) ? (all.push(i), all) : all;
          break;
        case "Function":
          return name.test(i[1].name) ? (all.push(i), all) : all;
          break;
        //数组 和 对象分开
        case "Array":
          var dd = searchObj(Object.entries(i[1]), name, deep).reduce((a, b) => {
            let num = parseInt(b[0]) - a.length;
            [...Array(num)].forEach(() => {
              a.push("***");
            });
            a.push(b[1]);
            return a;
          }, []);
          return dd.length ? (all.push([i[0], dd]), all) : all;
          break;
        case "Object":
          var bb = Object.fromEntries(searchObj(Object.entries(i[1]), name, deep));
          return Object.keys(bb).length === 0 ? all : (all.push([i[0], bb]), all);
          break;
        //跳过其他类型
        default:
          return all;
      }
    }
  }, []);
}
